console.inspectEnable = true;
import WebApp from 'webapp';
import { ICallBack, IDeviceCategory } from './interfaces/api.interface';
import { initSocketIO } from './libs/socket_server';
import devManager from './libs/sddc_device'
import loraManager from './libs/lora_device'
import mqttManager from './libs/mqtt_device'
import coapManager from './libs/coap_device'
import { LoRaDeviceInfo } from './libs/lora_device/type';
const app = WebApp.createApp();
app.use(WebApp.static('./public'));

// console.log(atob('mL0RkA==').toString())
// console.log(atob('mL0RkA==').toString('utf-8'))

const io = initSocketIO(app);
io.sockets.on('connection', (socket) => {
  socket.on('disconnect', () => {
    console.error('disconnect');
  });

  /* 获取指定类别的设备列表 */
  socket.on('list', (type: IDeviceCategory, cb: ICallBack) => {
    switch (type) {
      case 'device':
        cb({ result: true, message: '获取设备列表成功！', data: [...devManager.getDeviceList()] })
        break;
      case 'lora':
        cb({ result: true, data: loraManager.devs || [], message: '获取设备列表成功!' })
        break;
      default:
        console.error('Parameter error')
        break;
    }
  })

  /* 请求控制设备（sddc） */
  socket.on('request-control-device', (params: { type: IDeviceCategory, devid?: string }, cb: ICallBack) => {
    const { type, devid } = params
    switch (type) {
      case 'device':
        if (devid) {
          devManager.generateController(devid).then((controller) => {
            controller.on('message', (data) => {
              console.info('[device message]: ', data)
              emitMessage('message', { type, devid, data })
            })
            cb({ result: true, message: '控制设备成功！' })
          }, () => {
            cb({ result: false, message: '请求控制设备失败，请检查是否拥有设备控制权限或者重试！' })
          })
        }
        break;
      default:
        console.log('Parameter type error')
        break;
    }
  })

  /* 发送设备消息 */
  socket.on('send-message', (params: { type: IDeviceCategory, data: any }, cb: ICallBack) => {
    const { type, data } = params
    switch (type) {
      case 'device':
        if (data.devid) {
          devManager.sendDeviceInfo(data.devid, data.data).catch(() => {
            cb({ result: false, message: '消息发送失败，请重试！' })
          })
        }
        break;
      case 'lora':
        if (!loraManager.status) {
          const res = loraManager.initInstance()
          if (!res || !res.result) {
            return cb({ result: false, message: '服务端错误，请重试或者重启应用！' })
          }
        }
        if (!data.devEUI || !data.data) {
          cb({ result: false, message: '参数错误！' })
        } else {
          loraManager.sendMessage(data.devEUI, Buffer.from(data.data))
        }
        break
      case 'mqtt':
        if (mqttManager.getMqttClientStatus()) {
          mqttManager.sendMessage('message', data)
        } else {
          cb({ result: false, message: '当前mqtt连接断开！' })
        }
        break
      case 'coap':
        coapManager.put(data.url, data.path, data.data, (res) => {
          cb(res)
        })
        break
      default:
        console.log('Parameter type error')
        break;
    }
  })

  /* 获取mqtt服务当前状态 */
  socket.on('get-mqtt-status', (cb: ICallBack) => {
    cb({ result: true, message: '初始化mqtt信息成功！', data: mqttManager.getMqttClientStatus() })
  })

  /* 修改 MQTT 服务 */
  socket.on('change-mqtt-status', (status, cb: ICallBack) => {
    if (status) {
      // 连接到mqtt服务
      if (mqttManager.getMqttClientStatus()) {
        // mqtt服务已连接上，前端数据未同步
        emitMessage('mqttStatus', true)
        cb({ result: true, message: '连接MQTT服务成功！' })
      } else {
        // 连接mqtt服务
        mqttManager.connectServer(undefined, (res) => {
          if (res && res.result) {
            cb({ result: true, message: '连接MQTT服务成功！' })
          } else {
            cb({ result: false, message: '连接MQTT服务失败，请检查重试！' })
          }
        })
      }
    } else {
      // 断开mqtt服务
      mqttManager.disconnectServer()
    }
  })

  /* 连接 COAP 设备服务 */
  socket.on('connect-coap', (url: string, path = '/', cb: ICallBack) => {
    coapManager.get(url, path, (res) => {
      cb(res)
    })
  })
});

/* SDDC事件监听 */
devManager.on('join', (dev) => {
  emitMessage('list', { type: 'device', data: devManager.getDeviceList() })
});
devManager.on('lost', (dev) => {
  emitMessage('list', { type: 'device', data: devManager.getDeviceList() })
});
// devManager.on('error', (data) => {
//   io.emit('error', data);
// });


/* LORA事件监听 */
loraManager.on('message', (devEUI: string, data: any) => {
  emitMessage('message', { type: 'lora', devEUI, data: data })
})
loraManager.on('list', (data: LoRaDeviceInfo[]) => {
  emitMessage('list', { type: 'lora', data })
})

/* MQTT事件监听 */
mqttManager.on('connect', () => {
  emitMessage('mqttStatus', true)
})
mqttManager.on('disconnect', () => {
  emitMessage('mqttStatus', false)
})
mqttManager.on('message', (data) => {
  emitMessage('message', { type: 'mqtt', data: data })
})


/* 广播事件 */
function emitMessage(event: string, data?: any) {
  io.sockets.emit(event, data);
}

app.start();
require('iosched').forever();
